#ifndef _MATHLIB_H
#define _MATHLIB_H

#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

// 除法 v/(2^k) 向上取整
#define CEIL(v, k) (((v) + (1 << (k)) - 1) >> (k))
#define ICEIL(x, y) ((x) / (y) + ((x) % (y) != 0))

#define ROUNDUP(v, k) (((v) + (k)-1) & ~((k)-1))
#define ROUNDDOWN(v, k) ((v) & ~((k)-1))

/**
 * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
 * @n - parameter
 *
 * constant-capable log of base 2 calculation
 * - this can be used to initialise global variables from constant data, hence
 *   the massive ternary operator construction
 *
 * selects the appropriately-sized optimised version depending on sizeof(n)
 */
#define ilog2(n) ( __builtin_constant_p(n) ? ((n) == 0 ? 0 :\
		                        (n) & (1UL << 31) ? 31 :	\
		                        (n) & (1UL << 30) ? 30 :	\
		                        (n) & (1UL << 29) ? 29 :	\
		                        (n) & (1UL << 28) ? 28 :	\
		                        (n) & (1UL << 27) ? 27 :	\
		                        (n) & (1UL << 26) ? 26 :	\
		                        (n) & (1UL << 25) ? 25 :	\
		                        (n) & (1UL << 24) ? 24 :	\
		                        (n) & (1UL << 23) ? 23 :	\
		                        (n) & (1UL << 22) ? 22 :	\
		                        (n) & (1UL << 21) ? 21 :	\
		                        (n) & (1UL << 20) ? 20 :	\
		                        (n) & (1UL << 19) ? 19 :	\
		                        (n) & (1UL << 18) ? 18 :	\
		                        (n) & (1UL << 17) ? 17 :	\
		                        (n) & (1UL << 16) ? 16 :	\
		                        (n) & (1UL << 15) ? 15 :	\
		                        (n) & (1UL << 14) ? 14 :	\
		                        (n) & (1UL << 13) ? 13 :	\
		                        (n) & (1UL << 12) ? 12 :	\
		                        (n) & (1UL << 11) ? 11 :	\
		                        (n) & (1UL << 10) ? 10 :	\
		                        (n) & (1UL <<  9) ?  9 :	\
		                        (n) & (1UL <<  8) ?  8 :	\
		                        (n) & (1UL <<  7) ?  7 :	\
		                        (n) & (1UL <<  6) ?  6 :	\
		                        (n) & (1UL <<  5) ?  5 :	\
		                        (n) & (1UL <<  4) ?  4 :	\
		                        (n) & (1UL <<  3) ?  3 :	\
		                        (n) & (1UL <<  2) ?  2 :	\
		                        (n) & (1UL <<  1) ?  1 :    \
		                                            0) :    \
                                (31 - __builtin_clz(n)))

#endif /* _MATHLIB_H */